<script language="JScript" runAt="server">
// Check if file is called inside LBS
var inLBS;
if(inLBS!=true){
  Response.write("Invalid Call");
  Response.End();
}

//====== CLASS lbsXMLRPC ========================================
// XML-RPC Processer Class
//
// Copyright 2005 SiC. All Rights Reserved.
// Last Update: 2005-10-26 13:11:02
//============================================================

</script>
<%

// Create this object directly when included
// Must be put inside <% quotes to be available to the output Page
var xmlrpc=new lbsXMLRPC();

%>
<script language="JScript" runAt="server">

function lbsXMLRPC(){
  this.requestXML="";
  this.requestMethod="";

  this.errorCode=0;
  this.params=new Array();

  //====== Make a Call with XML-RPC ==========================================
  this.call = function(url, methodName, params){
    var callXML=this.getParamXML(params);
    callXML= "<?xml version=\"1.0\"?>\n<methodCall>\n<methodName>"+methodName+"</methodName>\n<params>"+callXML+"</params>\n</methodCall>";

    debug(func.HTMLEncode(callXML));
//    var objXMLHTTP = Server.CreateObject("Microsoft.XMLHTTP");
//    objXMLHTTP.open("POST", url, false);
//    objXMLHTTP.setRequestHeader("Content-Type","text/xml;charset=utf-8");
//  	objXMLHTTP.send(callXML);
    
  }

  // Convert Parameter Array to XML
  this.getParamXML = function(params,bStruct){
    var paramXML="";
    for(item in params){
      if(bStruct) paramXML+="<member><name>"+item+"</name>";
      paramXML+="<value>";
      switch(params[item].constructor){
        case Boolean:
          paramXML+="<boolean>"+(params[item]==true?"true":"false")+"</boolean>";
          break;
        case String:
          paramXML+="<string><![CDATA["+params[item]+"]]></string>";
          break;
        case Number:
          if(params[item]==Math.round(params[item])){
            paramXML+="<int>"+params[item]+"</int>";
          }else{
            paramXML+="<double>"+params[item]+"</double>";
          }
          break;
        case Date:
          paramXML+="<dateTime.iso8601>"+this.getISO8601Date(params[item])+"</dateTime.iso8601>";
          break;
        case Array:
          paramXML+="\n<array><data>\n"+this.getParamXML(params[item],false)+"</data></array>\n";
          break;
        case Object:
          paramXML+="\n<struct>\n"+this.getParamXML(params[item],true)+"</struct>\n";
          break;
      }
      paramXML+="</value>";
      if(bStruct) paramXML+="</member>";
      paramXML+="\n";
    }
    return paramXML;
  }

  // Get ISO8601 Date String
  this.getISO8601Date = function(objDate){
    var strDate="";
    strDate+=objDate.getFullYear();
    strDate+=(objDate.getMonth()+1)<10 ? "0"+(objDate.getMonth()+1) : (objDate.getMonth()+1);
    strDate+=objDate.getDate()<10 ? "0"+objDate.getDate() : objDate.getDate();
    strDate+="T";
    strDate+=objDate.getHours()<10 ? "0"+objDate.getHours() : objDate.getHours();
    strDate+=":";
    strDate+=objDate.getMinutes()<10 ? "0"+objDate.getMinutes() : objDate.getMinutes();
    strDate+=":";
    strDate+=objDate.getSeconds()<10 ? "0"+objDate.getSeconds() : objDate.getSeconds();
    
    return strDate;
  }

  //====== Parse the XML Text into methodName & Params ============================
  this.parse = function(){
    if(this.requestXML=="") this.requestXML=Request;
    var objDom = Server.CreateObject("Microsoft.XMLDOM");
    objDom.async=false;
    objDom.loadXML(this.requestXML);
    if(objDom.parseError.errorCode!=0){
      this.errorCode=101;
    }else{
      // Ready for select via XPath
      objDom.setProperty("SelectionLanguage", "XPath");
      objDom=objDom.documentElement;

      // Get the method name
      var objNodes = objDom.selectSingleNode("methodName");
      if(objNodes!=null){
        this.methodName=objNodes.text;
      }else{
        this.errorCode=102;
      }
      // Get params
      objNodes = objDom.selectNodes("//params/param");
      if(objNodes.length<1){
        this.errorCode=103;
      }else{
        try{
          for(var i=0;i<objNodes.length;i++){
            this.params[this.params.length]=this.getParamData(objNodes.item(i).selectSingleNode("value"));
          }
        }catch(e){
          this.errorCode=104;
        }
      }
    }
  }

  //====== Process a single param node ============================
  this.getParamData = function(objParamNode){
    if(objParamNode==null){
      return null;
    }
    var paramType=objParamNode.firstChild.tagName;
    if(paramType!=null){
      switch(paramType){
        case "string":
          return objParamNode.firstChild.text;
          break;
        case "i4":
          return parseInt(objParamNode.firstChild.text,10);
          break;
        case "int":
          return parseInt(objParamNode.firstChild.text,10);
          break;
        case "double":
          return parseFloat(objParamNode.firstChild.text);
          break;
        case "boolean":
          return (objParamNode.firstChild.text=="1" ? true : false);
          break;
        case "dateTime.iso8601":
          return this.parseISO8601Date(objParamNode.firstChild.text);
          break;
        case "base64":
          return objParamNode.firstChild.text; // Store the base64 text is better
          break;
        case "struct":
          return this.parseStruct(objParamNode.firstChild);
          break;
        case "array":
          return this.parseArray(objParamNode.firstChild);
          break;
      }
     }else{
       return objParamNode.text;
     }
  }

  // Parse <struct> node 
  this.parseStruct = function(objNode){
    var objMembers=objNode.selectNodes("member");
    if(objMembers.length<1){
      return null;
    }
    var structData=new Object();
    for(var i=0;i<objMembers.length;i++){
      structData[objMembers.item(i).selectSingleNode("name").text]=this.getParamData(objMembers.item(i).selectSingleNode("value"));
    }
    return structData;
  }

  // Parse <array> node 
  this.parseArray = function(objNode){
    var objData=objNode.selectSingleNode("data");
    if(objData==null) return null;
    var objValues=objData.selectNodes("value");
    if(objValues.length<1){
      return null;
    }
    var arrayData=new Array();
    for(var i=0;i<objValues.length;i++){
      arrayData[arrayData.length]=this.getParamData(objValues.item(i));
    }
    return arrayData;
  }

  // Parse ISO 8601 date string
  this.parseISO8601Date = function(strDate){
    var regexp = "([0-9]{4})(\-|)([0-9]{2})(\-|)([0-9]{2})( |T)([0-9]{2})(\:|)([0-9]{2})(\:|)([0-9]{2})";
    var d = strDate.match(new RegExp(regexp));

    var offset = 0;
    var date = new Date();

    if (d[1]) { date.setFullYear(d[1]); }
    if (d[3]) { date.setMonth(d[3] - 1); }
    if (d[5]) { date.setDate(d[5]); }
    if (d[7]) { date.setHours(d[7]); }
    if (d[9]) { date.setMinutes(d[9]); }
    if (d[11]) { date.setSeconds(d[11]); }

    d = strDate.match(/(\+|\-)([0-9]{2})(|:)(|[0-9]{2})/);
    if(d){
      if(d[2]) offset+=Number(d[2])*60;
      if(d[4]) offset+=Number(d[4]);
      if(d[1]=="+") offset = 0-offset;
    }

    offset -= date.getTimezoneOffset();
    time = (Number(date) + (offset * 60 * 1000));
    date.setTime(Number(time));
    return date;
  }

  //====== Normal Output ============================
  this.output = function(responseValue){
  	Response.ContentType="text/xml";
    Response.Write("<?xml version=\"1.0\"?>");
    Response.Write("<methodResponse><params><param><value>"+responseValue+"</value></param></params></methodResponse>");
  	Response.End();

  }

  //====== Error Output ============================
  this.errorOutput = function(errorCode, errorMessage){
  	Response.ContentType="text/xml";
    Response.Write("<?xml version=\"1.0\"?>");
    Response.Write("<methodResponse><fault><value><struct><member><name>faultCode</name><value><int>"+errorCode+"</int></value></member><member><name>faultString</name><value><string>"+errorMessage+"</string></value></member></struct></value></fault></methodResponse>");
  	Response.End();

  }

}
</script>